// =============================================================================
//  Spangles Analyzer
//
//  Copyright(c) 2008
//  See LICENSE.txt for licensing information.
// =============================================================================

package com.google.spangles.view.renderers;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;

import com.google.spangles.domain.Color;
import com.google.spangles.domain.Location;
import com.google.spangles.imaging.GeneratorService;
import com.google.spangles.imaging.impl.GeneratorServiceImpl;
import com.google.spangles.view.Renderer;
import com.google.spangles.view.Visualization;
import com.google.spangles.view.VisualizationElement;

/**
 * (Description)
 * (Any invariants [conditions that are always true] )
 * (Usage instructions, and/or examples)
 * (TODOs, ASSUMPTIONs, etc.)
 * (Known Bugs)
 * (Concurrency strategy - not thread safe or how it's thread safe)
 * 
 * @author Chris
 */
public class GraphicsRenderer implements Renderer
{
   GraphicsContext gc;
   
   Map<VisualizationElement, Integer> representations = new HashMap<VisualizationElement, Integer>();
   
   /**
    * @param go
    * @throws IOException 
    * @throws FileNotFoundException 
    */
   public GraphicsRenderer(GraphicsOptions go) throws FileNotFoundException, IOException
   {
      representations.put(new VisualizationElement(null, false), Integer.valueOf(GraphicsContext.EMPTY_DOWN));
      representations.put(new VisualizationElement(null, true), Integer.valueOf(GraphicsContext.EMPTY_UP));
      representations.put(new VisualizationElement(Color.WHITE, false), Integer.valueOf(GraphicsContext.WHITE_DOWN));
      representations.put(new VisualizationElement(Color.WHITE, true), Integer.valueOf(GraphicsContext.WHITE_UP));
      representations.put(new VisualizationElement(Color.BLACK, false), Integer.valueOf(GraphicsContext.BLACK_DOWN));
      representations.put(new VisualizationElement(Color.BLACK, true), Integer.valueOf(GraphicsContext.BLACK_UP));
      representations.put(new VisualizationElement(Color.GRAY, false), Integer.valueOf(GraphicsContext.GRAY_DOWN));
      representations.put(new VisualizationElement(Color.GRAY, true), Integer.valueOf(GraphicsContext.GRAY_UP));
      
      GeneratorService gs = new GeneratorServiceImpl();      
      gc = new GraphicsContext(go);      
      gs.generateImages(gc);
   }

   /* (non-Javadoc)
    * @see com.google.spangles.view.Renderer#render(com.google.spangles.view.Visualization)
    */
   public void render(Visualization v) throws IOException
   {
      // get rendering dimensions
      int x1 = v.getMinimumX();
      int x2 = v.getMaximumX();
      int xs = x2-x1+1;
      
      int y1 = v.getMinimumY();
      int y2 = v.getMaximumY();
      int ys = y2-y1+1;
      
      gc.prepareCanvas(xs, ys);
      
      // add the vertical ticks
      //for(int i=0;i<xs;i++)
      //{
      //   Character c = new Character((char)('A'+i));
      //   
      //   sb.render(0, 6+3*i, new String[]{c.toString(),"|"});
      //}
      
      //for(int i=0;i<ys;i++)
      //{
      //  String toShow = Integer.toString(i+1) + "_";
      //   
      //   sb.renderString(4+i*3, 3-toShow.length(), toShow);
      //}
      
      Collection<Location> ll = v.locations();
      
      for(Iterator<Location> li = ll.iterator(); li.hasNext(); )
      {
         Location l = li.next();
         int x = l.getX();
         int y = l.getY();
         VisualizationElement ve = v.getElement(l);
         
         Integer representation = representations.get(ve);
         
         gc.render(x-x1, y-y1, representation.intValue());         
      }
      
      BufferedImage bi = gc.getCanvas();
      ImageWriter iw = ImageIO.getImageWritersByFormatName("png").next();
      FileImageOutputStream fios = new FileImageOutputStream(new File("board.png"));      
      iw.setOutput(fios);
      iw.write(bi);
      fios.close();
   }

}
